//--------------------------------------------------------------------
//     Author:Howe
//     Date: 2021-04-13 21:46:32 
//     Description:对此文件的更改可能会导致不正确的行为，并且如果重新生成代码，这些更改将会丢失。
//--------------------------------------------------------------------
using Kylin.Wiki.Model.Entity;
using Kylin.Wiki.IService;
using Kylin.Wiki.Core.Extensions.AutofacManager;
using Kylin.Wiki.Model.Api;
using Kylin.Wiki.Model.Dto;
using Kylin.Wiki.Core.Utilities;
using Kylin.Wiki.Repository;
using Kylin.Wiki.Core.Extensions;
using Kylin.Wiki.Core.Configuration;
using Kylin.Wiki.Model.View;
using System.Collections.Generic;
using Kylin.Wiki.Core.Enum; 
using System.Linq;
using System;
using System.Linq.Expressions;
using Newtonsoft.Json;
using Mapster;

namespace Kylin.Wiki.Services
{
    /// <summary>
    /// UserServices
    /// </summary>	
    public class UserService : Service<User>, IUserService, IDependency
    { 
        private readonly IUser_RoleService _userRoleService;
        private readonly IRoleService _roleService;
        private readonly IRole_MenuService _role_MenuService;
        private readonly IMenuService _menuService;



        public UserService(IUnitOfWork unitOfWork,
            IRepository<User> repository, 
            IUser_RoleService user_RoleService,
            IRoleService roleService,
            IRole_MenuService role_MenuService,
            IMenuService menuService) : base(unitOfWork, repository)
        { 
            this._userRoleService = user_RoleService;
            this._roleService = roleService;
            this._role_MenuService = role_MenuService;
            this._menuService = menuService;
        }

        public ApiResult<object> Login(LoginDTO loginDto)
        {

            ApiResult<object> apiResult = new ApiResult<object>();
            var userInfo = base.FindFirst(o => o.UserName == loginDto.UserName.Trim());

            if (userInfo == null || loginDto.PassWord.Trim() != (userInfo.Password ?? "").DecryptDES(AppSetting.Secret.User))
            {
                apiResult.Code = Core.Enum.HttpStateCode.Error;
                apiResult.Message = "用户名或密码错误";
                apiResult.Success = false;
                return apiResult;
            }
            if (userInfo.Status.Value)
            {
                apiResult.Code = Core.Enum.HttpStateCode.Error;
                apiResult.Message = "用户未启用，请联系管理员！";
                apiResult.Success = false;
                return apiResult;
            }
            var roleID = _userRoleService.Find(x => x.UserID == userInfo.UserID).Select(x => x.RoleID).ToArray();
            string token = JwtHelper.IssueJwt(new UserInfo()
            {
                User_Id = userInfo.UserID,
                UserName = userInfo.UserName,
                DeptID = userInfo.DeptID.Value,
                DisplayName = userInfo.DisplayName,
                RoleID = roleID
            });

            apiResult.Success = true;
            apiResult.Data =token;
            return apiResult;
        }

        public ApiPageResult<List<UserVM>> GetList(UserDTO userDTO)
        {
            ApiPageResult<List<UserVM>> apiPageResult = new ApiPageResult<List<UserVM>>();
            var orderBy = new Dictionary<string, QueryOrderBy>() { {
                    userDTO.Sort, userDTO.OrderBy?.ToLower() =="asc"? QueryOrderBy.Asc: QueryOrderBy.Desc
             } };
            var data = base.QueryablePage(userDTO.PageIndex,
                userDTO.PageSize,
                out int rowCount,
                null,
                orderBy);
            if (!string.IsNullOrEmpty(userDTO.UserName))
                data = data.Where(x => x.UserName == userDTO.UserName).ToList();
            if (!string.IsNullOrEmpty(userDTO.Mobile))
                data = data.Where(x => x.Mobile == userDTO.Mobile).ToList();

            var suser = data.Adapt<List<UserVM>>();
            //查询用户角色
            suser.ForEach(x => x.Roles = _userRoleService.Find(v => v.UserID == x.UserID).Select(v => v.RoleID).ToArray());

            apiPageResult.Data = suser;
            apiPageResult.TotalCount = rowCount;
            apiPageResult.PageIndex = userDTO.PageIndex;
            apiPageResult.PageSize = userDTO.PageSize;
            apiPageResult.TotalPages = (rowCount % userDTO.PageSize) > 0 ? rowCount / userDTO.PageSize + 1 : rowCount / userDTO.PageSize;
            return apiPageResult;
        }

        public ApiResult<bool> CreateUser(CreateUserDTO createUserDTO)
        {
            var user =createUserDTO.Adapt<User>();
            user.CreateOn = DateTime.Now;
            user.UpdateOn = DateTime.Now;
            user.Status = false;
            user.Password = user.Password.EncryptDES(AppSetting.Secret.User);
            if (base.Exists(x => x.UserName.Equals(createUserDTO.UserName)))
                return new ApiResult<bool>(false, HttpStateCode.Error, "该用户名已存在");
            //添加用户
            base.Add(user, true);
            if (user.UserID > 0)
            {
                List<User_Role> user_Roles = new List<User_Role>();
                foreach (var item in createUserDTO.Roles)
                {
                    User_Role user_Role = new User_Role
                    {
                        CreateBy = user.CreateBy,
                        CreateOn = DateTime.Now,
                        UpdateBy = user.UpdateBy,
                        UpdateOn = DateTime.Now,
                        IsDelete = "0",
                        UserID = user.UserID,
                        RoleID = item,
                    };
                    user_Roles.Add(user_Role);
                }
                _userRoleService.AddRange(user_Roles, true);
            }
            return new ApiResult<bool>(true, HttpStateCode.Success, "添加成功");

        }

        public ApiResult<bool> UpdateUser(UpdateUserDTO updateUserDTO)
        {
            //判断是否存在该用户
            if (!base.Exists(x => x.UserID == updateUserDTO.UserID))
                return new ApiResult<bool>(false, HttpStateCode.Error, "该用户不存在");
            //删除该用户现有权限
            var userRoles = _userRoleService.Find(x => x.UserID == updateUserDTO.UserID);
            foreach (var item in userRoles)
            {
                _userRoleService.Delete(item, true);
            }

            Expression<Func<User, object>>[] updatedProperties =
            {
                   p=>p.Avatar,
                   p=>p.UserName,
                   p=>p.DisplayName,
                   p=>p.DeptID,
                   p=>p.Mobile,
                   p=>p.Email,
                   p=>p.UpdateBy,
                   p=>p.UpdateOn
            };
            var user =updateUserDTO.Adapt<User>();

            base.Update(user, updatedProperties, true);

            //添加用户权限啊
            List<User_Role> user_Roles = new List<User_Role>();
            foreach (var item in updateUserDTO.Roles)
            {
                User_Role user_Role = new User_Role
                {
                    CreateBy = user.CreateBy,
                    CreateOn = DateTime.Now,
                    UpdateBy = user.UpdateBy,
                    UpdateOn = DateTime.Now,
                    IsDelete = "0",
                    UserID = user.UserID,
                    RoleID = item,
                };
                user_Roles.Add(user_Role);
            }
            _userRoleService.AddRange(user_Roles, true);
            return new ApiResult<bool>(true, HttpStateCode.Success, "更新成功");

        }


        public ApiResult<UserInfoVM> GetUserInfo(int userId)
        {
            ApiResult<UserInfoVM> result = new ApiResult<UserInfoVM>();
            var user = base.FindFirst(x => x.UserID == userId);
            if (user == null)
                return new ApiResult<UserInfoVM>(false, HttpStateCode.Error, "用户不存在");
            UserInfoVM userInfoVM = new UserInfoVM();
            userInfoVM.UserInfo = user.Adapt<UserVM>();
            var roles = _userRoleService.Find(v => v.UserID == userId).Select(v => v.RoleID).ToArray();
            userInfoVM.Roles = (from a in roles
                                join b in _roleService.Find(x => 1 == 1).ToList() on a equals b.RoleID
                                select b.RoleName)
                                .ToList();

            var auth = (from a in roles
                        join b in _role_MenuService.Find(x => 1 == 1)
                        on a equals b.RoleID
                        select b.MenuID);
            var metas = (from a in auth
                         join b in _menuService.Find(x => 1 == 1) on a equals b.MenuID
                         select b.Meta).ToList();
            userInfoVM.Auth = new List<string>();
            foreach (var item in metas)
            {
                var meta = JsonConvert.DeserializeObject<MetaVM>(item);
                userInfoVM.Auth.AddRange(meta.Auth);
            }

            result.Data = userInfoVM;

            return result;
        }
    }



}